package com.itheima.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;
import javax.jms.Queue;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.alibaba.fastjson.JSON;
import com.itheima.dto.AccountExportDTO;
import com.itheima.mapper.AccountMapper;
import com.itheima.utils.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.itheima.config.ActiveMqBean;
import com.itheima.dto.UserDTO;
import com.itheima.entity.ExcelModel;
import com.itheima.entity.UserInfo;
import com.itheima.enums.MsgCode;
import com.itheima.exceptions.CustomException;
import com.itheima.mapper.UserInfoMapper;
import com.itheima.service.UserService;

/**
 * @Date :2019-08-15 17:35
 * @Author : yuan_he_song
 */
@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserInfoMapper userInfoMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private JwtUtils jwtUtils;
    @Autowired
    private HttpSession session;
    @Autowired
    private Queue queue;

    @Override
    public UserDTO login(String phone, String password) {

        UserDTO userDTO = new UserDTO();
        // 1. 根据用户名和密码查询用户是否存在
        UserInfo userInfo = userInfoMapper.selectByPhoneAndPassword(phone,password);

        // 2.若存在,生成token返回前端
        if(userInfo != null ){
            BeanUtils.copyProperties(userInfo,userDTO);
            String token= jwtUtils.createToken(userInfo.getUserId() + "", userInfo.getUserPhone(), null);
            userDTO.setToken(token);
            session.setAttribute(ResultUtils.CURRENT_USER,userDTO);
            return userDTO;
        }
        throw new CustomException(MsgCode.ERROR_USER_NAME);

    }

    @Override
    public int register(UserInfo userInfo) {
        /** 添加数据 */
        return userInfoMapper.insertSelective(userInfo);
    }

    @Transactional
    public int batchInsert(List<ExcelModel> datas) {
        List<UserInfo> list = Lists.newArrayList();
        for (ExcelModel data : datas) {
            UserInfo userInfo = new UserInfo();
            BeanUtils.copyProperties(data,userInfo);
            if("男".equals(data.getSex())){
                userInfo.setUserSex(1);
            }else {
                userInfo.setUserSex(0);
            }
            list.add(userInfo);
        }

        return userInfoMapper.batchInsert(list);
    }

    @Override
    public void generateCode(String phone) {
        // 生成6位随机数字(验证码)
        int sysCode = (int)(Math.random()*1000000);
        // 以电话号码为key,验证码位value存入redis
        redisTemplate.boundHashOps("sms").put(phone,sysCode+"");
        // 把验证码发给MQ,MQ调用短信服务发送短信
        Map<String,String> map = Maps.newHashMap();
        map.put("phone",phone);
        map.put("sysCode",sysCode+"");
        System.err.println("验证码: "+sysCode);
        ActiveMqUtil.sendMsg(JSON.toJSONString(map), ActiveMqBean.MyQueue, 10000L);
    }

    @Resource
    private AccountMapper accountMapper;

    @Override
    public void export(HttpServletRequest request, HttpServletResponse response)throws Exception {
        // 设置自适应宽度
        String fileName = FileUtils.encodeDownloadFilename("订单信息",request.getHeader("user-agent"));

        // 分页查询数据
        int fromIndex = 1;
        int pageSize = 5000;
        int dataLength = pageSize;
        List<AccountExportDTO> dadaResult = Lists.newArrayList();
        Map<String,Integer> map = new HashMap<>();
        while (pageSize == dataLength){
            map.put("start", (fromIndex++ - 1) * pageSize);
            map.put("size",pageSize);
            dadaResult = accountMapper.findByConditions(map);
            if (dadaResult.isEmpty()){
                ExcelUtils.export("sheet1",fileName,AccountExportDTO.class,dadaResult);
                break;
            }
            dataLength = dadaResult.size();
            ExcelUtils.export("sheet1",fileName,AccountExportDTO.class,dadaResult);
        }

    }

    /**
     * map排序
     */
    public static void main(String[] args) {
        Map<Integer, UserInfo> map = new HashMap<>();
        map.put(1,new UserInfo("aaa", 58));
        map.put(2,new UserInfo("bbb", 28));
        map.put(3,new UserInfo("ccc", 65));
        map.put(4,new UserInfo("ddd", 12));
        Map<Integer, UserInfo> resultMap= sortMap(map);
        System.out.println("排序后的map:"+resultMap);

        /**
         *  冒泡排序
         */
        int[] arr = { 6, 3, 8, 2, 9, 1 };
        for (int i = 0; i < arr.length - 1 ; i++) {
            for (int j = 0; j < arr.length -1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    // 交换位置 异或运算
                    arr[j] = arr[j] ^ arr[j + 1];
                    arr[j + 1] = arr[j] ^ arr[j + 1];
                    arr[j] = arr[j] ^ arr[j + 1];
                }
            }
        }

        System.out.println("排序后:");
        // 排序后的新数组
        for (int i : arr) {
            System.out.print(i + " ");
        }

    }

    /**
     * @Description: 给map排序
     * @date: 2019年4月16日 下午12:09:33
     * @author: yuan_he_song
     * @param map 传递过来的数据
     */
    private static Map<Integer, UserInfo> sortMap(Map<Integer, UserInfo> map) {

        LinkedHashMap<Integer, UserInfo> resultMap = new LinkedHashMap<Integer, UserInfo>();
        Set<Map.Entry<Integer,UserInfo>> set = map.entrySet();

        // 将set转为list,通过构造相互转化,方便用Collections工具类
        List<Map.Entry<Integer,UserInfo>> list = new ArrayList<>(set);
        Collections.sort(list, new Comparator<Map.Entry<Integer,UserInfo>>() {
            @Override
            public int compare(Map.Entry<Integer,UserInfo> o1, Map.Entry<Integer,UserInfo> o2) {
                /**  按年龄从小到大排序 */
                return o1.getValue().getAge() - o2.getValue().getAge();
                // return o2.getValue().getAge() - o1.getValue().getAge(); 按年龄倒序
            }
        });
        for (Map.Entry<Integer, UserInfo> entry : list) {
            resultMap.put(entry.getKey(), entry.getValue());
        }
        return resultMap;
    }
}
